package com.tangruojie.stream;

import com.tangruojie.entity.Author;

import java.util.List;
import java.util.function.BinaryOperator;

/**
 * 终结操作 reduce 把流中的多个元素，按照某种规则合并为一个值（如求和、拼接、求最大值等）
 * 它是一个通用版本的累加器，相比 sum()、count() 更灵活、功能更强
 */
public class StreamDemo15 {

    /**
     * 参数名	        解释
     * identity	        初始值
     * accumulator	    累加函数（怎么合并两个元素）
     * combiner	        并行时合并多个中间结果（第三个版本用）
     */

    public static void main(String[] args) {

        List<Author> authors = StreamDemoTest.getAuthors();

        /**
         * T reduce(T identity, BinaryOperator<T> accumulator); 的底层实现
         * U result = identity;
         * for (T element : this stream)
         *     result = accumulator.apply(result, element);
         * return result;
         */
        /**
         * 所有作者年龄之和
         */
        Integer integer = authors.stream()
                .distinct()
                .map(Author::getAge)
                .reduce(0, new BinaryOperator<Integer>() {
                    @Override
                    public Integer apply(Integer integer, Integer integer2) {
                        return integer + integer2;
                    }
                });
        System.out.println(integer);

        /**
         * T reduce(T identity, BinaryOperator<T> accumulator); 的底层实现
         * boolean foundAny = false;
         * T result = null;
         * for (T element : this stream) {
         *     if (!foundAny) {
         *         foundAny = true;
         *         result = element;
         *     } else {
         *         result = accumulator.apply(result, element);
         *     }
         * }
         * return foundAny ? Optional.of(result) : Optional.empty();
         */
        /**
         * 所有作者年龄最大值
         */
        authors.stream()
                .distinct()
                .map(Author::getAge)
                .reduce(new BinaryOperator<Integer>() {
                    @Override
                    public Integer apply(Integer integer, Integer integer2) {
                        return integer > integer2 ? integer : integer2;
                    }
                })
                .ifPresent(System.out::println);

        /**
         * 所有作者姓名连接在一个字符串中
         */
        authors.stream()
                .distinct()
                .map(Author::getName)
                .reduce(new BinaryOperator<String>() {
                    @Override
                    public String apply(String s, String s2) {
                        return s + "，" + s2;
                    }
                })
                .ifPresent(System.out::println);

    }

}
/**
 * 功能	    reduce()	            collect()
 * 用于	    聚合单个结果	            聚合结构化数据（List/Map）
 * 结果类型	一个值（数字、字符串等）	集合、Map、统计对象等
 * 适合	    总和、拼接、最大值、乘积等	分组、收集、计数、连接字符串等
 * reduce() 是将多个元素合并成一个结果的万能函数式工具，相当于一个自定义的 “累加器”，比 .sum() 等更灵活强大。
 */